/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 *
 * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
 *
 * Contributor(s): 
 *  Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
 *  
 * If you didn't download this code from the following link, you should check
 * if you aren't using an obsolete version: http://www.isqlviewer.com
 */
package org.isqlviewer.ui;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.text.MessageFormat;
import java.util.prefs.Preferences;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.isqlviewer.history.HistoricalCommand;
import org.isqlviewer.sql.QueryMetadata;
import org.isqlviewer.swing.EnhancedTable;
import org.isqlviewer.swing.SwingUtilities;
import org.isqlviewer.swing.action.SwingEventManager;
import org.isqlviewer.swing.table.EnhancedTableModel;
import org.isqlviewer.util.LocalMessages;
import org.isqlviewer.util.StringUtilities;

/**
 * @author Mark A. Kobold &lt;mkobold at isqlviewer dot com&gt;
 * @version 1.0
 */
public class DataGrid extends AbstractApplicationView implements ListSelectionListener, DocumentListener {

    private static final MessageFormat cursorFormat = new MessageFormat("{0}/{1}");
    private LocalMessages messages = new LocalMessages("org.isqlviewer.ui.ResourceBundle");

    private EnhancedTable table = null;
    private EnhancedTableModel model = null;
    private HistoricalCommand queryReference = null;

    private JLabel lblFilter = new JLabel();
    private JLabel cursorLabel = new JLabel(SwingUtilities.loadIconResource("table", 16));
    private JLabel serviceLabel = new JLabel(SwingUtilities.loadIconResource("service", 16));
    private JLabel timeLabel = new JLabel(SwingUtilities.loadIconResource("history", 16));

    private JTextField searchText = new JTextField(8);

    public void configureMenubar(JMenuBar menuBar) {

    }

    public void disposeView(Preferences preferences) {

    }

    public void initializeView() {

    }

    public void doLayout(JComponent parentComponent, Preferences preferences, SwingEventManager eventManager) {

        table = new EnhancedTable();
        table.setDragEnabled(true);
        table.getSelectionModel().addListSelectionListener(this);
        searchText.getDocument().addDocumentListener(this);

        cursorLabel.setBorder(BorderFactory.createEtchedBorder());
        cursorLabel.setToolTipText(messages.format("DataGrid.current_position_of_selection"));
        timeLabel.setBorder(BorderFactory.createEtchedBorder());
        timeLabel.setToolTipText(messages.format("DataGrid.time_spent_aquiring_these_results"));
        serviceLabel.setBorder(BorderFactory.createEtchedBorder());
        serviceLabel.setToolTipText(messages.format("DataGrid.service_these_results_came_from"));

        JScrollPane dataScrollPanel = new JScrollPane(table);
        Object UI_CONSTRAINT = null;

        JPanel searchBar = new JPanel(new GridBagLayout());
        UI_CONSTRAINT = constrain(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        searchBar.add(Box.createHorizontalGlue(), UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        JLabel searchLabel = new JLabel(SwingUtilities.loadIconResource("search", 16));
        searchBar.add(searchLabel, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        searchBar.add(searchText, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        searchBar.add(Box.createHorizontalStrut(10), UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE);
        searchBar.add(lblFilter, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        searchBar.add(Box.createHorizontalStrut(10), UI_CONSTRAINT);

        JPanel statusBar = new JPanel(new GridBagLayout());
        UI_CONSTRAINT = constrain(3, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        statusBar.add(Box.createHorizontalGlue(), UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE);
        statusBar.add(timeLabel, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE);
        statusBar.add(serviceLabel, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE);
        statusBar.add(cursorLabel, UI_CONSTRAINT);

        parentComponent.setLayout(new BorderLayout());
        parentComponent.add(searchBar, BorderLayout.NORTH);
        parentComponent.add(dataScrollPanel, BorderLayout.CENTER);
        parentComponent.add(statusBar, BorderLayout.SOUTH);
    }

    public void changedUpdate(DocumentEvent e) {

    }

    public void insertUpdate(DocumentEvent e) {

        doFiltering();
    }

    public void removeUpdate(DocumentEvent e) {

        doFiltering();
    }

    public void valueChanged(ListSelectionEvent e) {

        Object[] arguments = new Object[2];
        arguments[0] = Integer.toString(table.getSelectedRow() + 1);
        arguments[1] = Integer.toString(table.getRowCount());
        synchronized (cursorLabel) {
            cursorLabel.setText(cursorFormat.format(arguments));
        }
    }

    public void setMetadata(QueryMetadata metadata) {

        this.queryReference = metadata.getCommand();
        serviceLabel.setText(metadata.getService());
        timeLabel.setText(StringUtilities.getHumanReadableTime(metadata.getUserTime()));
    }

    public void setModel(EnhancedTableModel model) {

        this.model = model;
        table.setModel(model);
        if (model.getTrueRowCount() >= 1) {
            table.setRowSelectionInterval(0, 0);
        }
    }

    public EnhancedTable getTable() {

        return table;
    }

    public HistoricalCommand getQueryReference() {

        return queryReference;
    }

    public void clearFiltering() {

        if (model != null) {
            model.clearFilter();
        }
        searchText.setText(null);
        lblFilter.setText(null);
    }

    private synchronized void doFiltering() {

        if (model != null) {
            String filter = searchText.getText().trim();
            int found = model.applyFilter(filter);
            if (found >= 1) {
                String txt = messages.format("datagrid.found_matches", Integer.toString(found));
                lblFilter.setText(txt);
            } else {
                if (filter.length() >= 1) {
                    lblFilter.setText(messages.getMessage("datagrid.no_matches"));
                } else {
                    lblFilter.setText(null);
                }
            }
            if (table.getRowCount() >= 1) {
                table.setRowSelectionInterval(0, 0);
            }
            table.invalidate();
        }
    }
}